﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace NetworkDemo
{
    public class GameController
    {
        ScreenManager gameView;
        NetworkManager gameNetwork;
        Game1 gameModel;


        public GameController(Game1 model)
        {
            gameModel = model;
            gameView = new ScreenManager(model, this);
            gameNetwork = new NetworkManager(this);
            gameNetwork.netstatusEvent += new NetstatusEventHandler(OnNetStatusChanged);
        }

        #region Events
        #region Network
        public void OnNetStatusChanged(object sender, NetstatusEventArgs e)
        {
            if (e.NetStatus == NetConnectionStatus.Disconnected)
            {
               Screen A = gameView.GetScreen("GameplayScreen");
               if (A != null)
               {
                   A.ExitScreen();
                   LoadingScreen.Load(gameView, true, gameView.GetScreen("MainMenu"));
               }
            }
        }
        #endregion
        #region Main Menu
        /// <summary>
        /// This should be connecting to the server; it'll get a response back as a netstatus change
        /// event that will do the rest.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnJoinGame(object sender, EventArgs e)
        {
            Screen A = new NetworkPopupScreen(gameModel.backgroundTexture, gameModel.borderTexture, gameNetwork);
            gameView.AddScreen(A);
            
        }

        public void OnQuitGame(object sender, EventArgs e)
        {
            Environment.Exit(1);
        } // Got to here. Consider starting on the server now, which will feed player data 

        #endregion
        #endregion

        #region Gameplay Initialization

        public void StartGameplay()
        {
            LoadingScreen.Load(gameView, true, new GameplayScreen());
        }
        #endregion

        #region Network
        public void HandleNetworkData(NetBuffer buffer)
        {
            string msg = buffer.ReadString();
            switch (msg)
            {
                case "id":
                    HandleBuffer_Id(buffer);
                    break;
                case "updateplayer":
                    HandleBuffer_UpdatePlayer(buffer);
                    //gameController.UpdatePlayer(buffer);
                    break;
                case "allplayers":
                    HandleBuffer_AllPlayers(buffer);
                    //gameController.UpdatePlayers(buffer);
                    break;
                default:
                    break;
            }
        }

        #region Buffer handlers
        public void HandleBuffer_Id(NetBuffer buffer)
        {
            if (gameModel.PlayerManager.ClientPlayer != null)
                return; // Client already has a player
            UInt32 id = buffer.ReadUInt32(3);
            Player P = gameModel.PlayerManager.CreatePlayer("Player" + id, (int)id, Vector2.Zero);
            gameModel.PlayerManager.AddPlayer(P);
            gameModel.PlayerManager.ClientPlayer = P;
            StartGameplay();
        }

        public void HandleBuffer_UpdatePlayer(NetBuffer buffer)
        {
            gameModel.PlayerManager.UpdatePlayer(buffer);
        }

        public void HandleBuffer_AllPlayers(NetBuffer buffer)
        {
            gameModel.PlayerManager.UpdatePlayers(buffer);
        }
        #endregion
        #endregion
        public void PushNetworkUpdate()
        {
            if(gameModel.PlayerManager.ClientPlayer != null && gameModel.PlayerManager.ClientPlayer.Dirty) 
                gameNetwork.PushNetworkUpdate(gameModel.PlayerManager.ClientPlayer);
        }

        #region Player movement
        public void MoveClientSprite(Keys dir)
        {
            Player P;
            Vector2 S;
            if((P = gameModel.PlayerManager.ClientPlayer) == null) return;
            if((S = P.MySprite.Position) == null) S = new Vector2(0.0f, 0.0f);
            P.Dirty = true;
            if (dir == Keys.Down)
                S.Y += 2.0f;
            if (dir == Keys.Up)
                S.Y -= 2.0f;
            if(dir == Keys.Left)
                S.X -= 2.0f;
            if(dir == Keys.Right)
                S.X += 2.0f;

            P.MySprite.Position = Vector2.Clamp(S, Vector2.Zero, new Vector2(1280.0f - P.MySprite.Texture.Width, 1024.0f - P.MySprite.Texture.Height));
        }
        #endregion
    }
}